/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Collections;
using System.Data;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace ELE.EnterpriseLibrary.Data
{
  /// <summary>
  /// This interface defines a contract used to run database queries on a relational database
  /// <para>The contract defines the functionality to be used when retrieving or persisting data 
  /// stored in objects into a relational database that has been mapped to an object oriented structure.</para>
  /// </summary>
  public interface IObjectQueryRunner
  {
    /// <summary>
    /// Executes an identified stored procedure using the inputs from a given object and return a DataSet with the results.
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="storedProcedureId">The id of the stored procedure</param>
    /// <param name="inputObject">The object that contains the values to insert in the query</param>
    /// <returns>The resulting rows from the database</returns>
    DataSet ExecuteDatasetStoredProcedureByName(Database database, string storedProcedureId, object inputObject);
    /// <summary>
    /// Executes an identified stored procedure using the inputs from a given object and return an IList with the results.
    /// <para>The IList contains rich objects of type(s) that are mapped to the query by the underlying ORM implementation.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="storedProcedureId">The id of the stored procedure</param>
    /// <param name="inputObject">The object that contains the values to insert in the query</param>
    /// <returns>The resulting objects from the database</returns>
    IList ExecuteStoredProcedureByName(Database database, string storedProcedureId, object inputObject);
    /// <summary>
    /// Executes an identified query using the inputs from a given object and return a DataSet with the results.
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="queryId">The id of the query</param>
    /// <param name="inputObject">The object that contains the values to insert in the query</param>
    /// <returns>The resulting rows from the database</returns>
    DataSet ExecuteDatasetQueryByName(Database database, string queryId, object inputObject);
    /// <summary>
    /// Executes an identified query using the inputs from a given object and return a data reader with the results.
    /// <para>The difference between this method and <see cref="IObjectQueryRunner.ExecuteDatasetQueryByName(Database,string,object)"/> 
    /// is that this method is meant to be used for lightweight iteration through records without the overhead of using DataSets.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="queryId">The id of the query</param>
    /// <param name="inputObject">The object that contains the values to insert in the query</param>
    /// <returns>The resulting rows from the database</returns>
    IDataReader ExecuteDatareaderQueryByName(Database database, string queryId, object inputObject);
    /// <summary>
    /// Executes an identified query using the inputs from a given object and return an IList with the results.
    /// <para>The IList contains rich objects of type(s) that are mapped to the query by the underlying ORM implementation.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="queryId">The id of the query</param>
    /// <param name="inputObject">The object that contains the values to insert in the query</param>
    /// <returns>The resulting objects from the database</returns>
    IList ExecuteQueryByName(Database database, string queryId, object inputObject);
    /// <summary>
    /// Executes an identified query using the inputs from a given object and return an IList with the results.
    /// <para>The IList contains plain objects of type(s) that are mapped to the query by the underlying ORM implementation.</para>
    /// <para>The difference between this method and <see cref="IObjectQueryRunner.ExecuteQueryByName(Database,string,object)"/> is 
    /// that this method does not cascade down to the object structure mapped by the ORM and returns a flat view of the 
    /// object only.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="queryId">The id of the query</param>
    /// <param name="inputObject">The object that contains the values to insert in the query</param>
    /// <returns>The resulting objects from the database</returns>
    IList ExecuteQueryByNameLightweight(Database database, string queryId, object inputObject);

    /// <summary>
    /// Retrieve an object from the database by using the pkValue provided to match to the primary 
    /// key column of the primary table mapped by the ORM to the given objectId in the default mapping set.
    /// <para>The returned object is a rich object that contains all data found on referenced bindings.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="objectId">The id of the object from the default mapping.</param>
    /// <param name="pkValue">the value to match with the primary key.</param>
    /// <returns>The object whose primary key property matches the given primary key or null if no match is found</returns>
    object QueryObjectByPrimaryKey(Database database, string objectId, object pkValue);
    /// <summary>
    /// Retrieve an object from the database by using the pkValue provided to match to the primary 
    /// key column of the primary table mapped by the ORM to the given objectId within the mapping set that matches the given mappingId. 
    /// <para>The returned object is a rich object that contains all data found on referenced bindings.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="mappingId">The id of the mapping to be used</param>
    /// <param name="objectId">The id of the object from the given mapping.</param>
    /// <param name="pkValue">the value to match with the primary key.</param>
    /// <returns>The object whose primary key property matches the given primary key or null if no match is found</returns>
    object QueryObjectByPrimaryKey(Database database, string mappingId, string objectId, object pkValue);
    /// <summary>
    /// Lightweight version of <see cref="IObjectQueryRunner.QueryObjectByPrimaryKey(Database, string, object)"/> in which 
    /// the returned object is flat and not populated with data from referenced objects.
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="objectId">The id of the object from the default mapping.</param>
    /// <param name="pkValue">the value to match with the primary key.</param>
    /// <returns>The object whose primary key property matches the given primary key or null if no match is found</returns>
    object QueryObjectByPrimaryKeyLightweight(Database database, string objectId, object pkValue);
    /// <summary>
    /// Lightweight version of <see cref="IObjectQueryRunner.QueryObjectByPrimaryKey(Database, string, string, object)"/> in which 
    /// the returned object is flat and not populated with data from referenced objects.
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="mappingId">The id of the mapping to be used</param>
    /// <param name="objectId">The id of the object from the given mapping.</param>
    /// <param name="pkValue">the value to match with the primary key.</param>
    /// <returns>The object whose primary key property matches the given primary key or null if no match is found</returns>
    object QueryObjectByPrimaryKeyLightweight(Database database, string mappingId, string objectId, object pkValue);

    /// <summary>
    /// Retrieve an object from the database by using the bound property of the inputValue that is tied to 
    /// a column of a table mapped by the ORM to the given objectId in the default mapping set.
    /// <para>The returned object is a rich object that contains all data found on referenced bindings.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="objectId">The id of the object from the default mapping.</param>
    /// <param name="propertyName">The name of the binding that defines the bound property.</param>
    /// <param name="inputValue">The object that contains the value to match.</param>
    /// <returns>A list of objects that match the given property</returns>
    IList QueryObjectByProperty(Database database, string objectId, string propertyName, object inputValue);
    /// <summary>
    /// Retrieve an object from the database by using the bound property of the inputValue that is tied to 
    /// a column of a table mapped by the ORM to the given objectId in the mapping set that matches the given mappingId.
    /// <para>The returned object is a rich object that contains all data found on referenced bindings.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="mappingId">The id of the mapping.</param>
    /// <param name="objectId">The id of the object from the given mapping.</param>
    /// <param name="propertyName">The name of the binding that defines the bound property.</param>
    /// <param name="inputValue">The object that contains the value to match.</param>
    /// <returns>A list of objects that match the given property</returns>
    IList QueryObjectByProperty(Database database, string mappingId, string objectId, string propertyName, object inputValue);
    /// <summary>
    /// Lightweight version of <see cref="IObjectQueryRunner.QueryObjectByProperty(Database,string,string,object)"/> in which 
    /// the returned object is flat and not populated with data from referenced objects.
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="objectId">The id of the object from the default mapping.</param>
    /// <param name="propertyName">The name of the binding that defines the bound property.</param>
    /// <param name="inputValue">The object that contains the value to match.</param>
    /// <returns>A list of objects that match the given property</returns>
    IList QueryObjectByPropertyLightweight(Database database, string objectId, string propertyName, object inputValue);
    /// <summary>
    /// Lightweight version of <see cref="IObjectQueryRunner.QueryObjectByProperty(Database,string,string,string,object)"/> in which 
    /// the returned object is flat and not populated with data from referenced objects.
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="mappingId">The id of the mapping.</param>
    /// <param name="objectId">The id of the object from the given mapping.</param>
    /// <param name="propertyName">The name of the binding that defines the bound property.</param>
    /// <param name="inputValue">The object that contains the value to match.</param>
    /// <returns>A list of objects that match the given property</returns>
    IList QueryObjectByPropertyLightweight(Database database, string mappingId, string objectId, string propertyName, object inputValue);
    
    /// <summary>
    /// Persist an object to the underlying relational database.
    /// <para>Implementations of this method must cascade down to all bound properties and persist all 
    /// objects contained within the given objectToPersist that are mapped by referenced bindings</para>
    /// <para>The implementation should be smart enough to determine whether an insert or update statement 
    /// is necessary for persistance.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="objectId">The id of the object from the default mapping.</param>
    /// <param name="objectToPersist">The object to store.</param>
    /// <returns>The number of rows affected by the transaction</returns>
    int PersistObject(Database database, string objectId, object objectToPersist);
    /// <summary>
    /// Persist an object to the underlying relational database.
    /// <para>Implementations of this method must cascade down to all bound properties and persist all 
    /// objects contained within the given objectToPersist that are mapped by referenced bindings</para>
    /// <para>The implementation should be smart enough to determine whether an insert or update statement 
    /// is necessary for persistance.</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="mappingId">The mapping that defines the object persistance information.</param>
    /// <param name="objectId">The id of the object from the given mapping.</param>
    /// <param name="objectToPersist">The object to store.</param>
    /// <returns>The number of rows affected by the transaction</returns>
    int PersistObject(Database database, string mappingId, string objectId, object objectToPersist);

    /// <summary>
    /// Removes an object from the underlying relational database by matching the primary binding of the object.
    /// <para>Implementations of this method must cascade down to all bound properties and remove all 
    /// objects contained within the given objectToRemove that are mapped by referenced bindings</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="objectId">The id of the object from the default mapping.</param>
    /// <param name="objectToRemove">The object to remove.</param>
    /// <returns>The number of rows affected by the transaction</returns>
    int RemoveObject(Database database, string objectId, object objectToRemove);
    /// <summary>
    /// Removes an object from the underlying relational database by matching the primary binding of the object.
    /// <para>Implementations of this method must cascade down to all bound properties and remove all 
    /// objects contained within the given objectToRemove that are mapped by referenced bindings</para>
    /// </summary>
    /// <param name="database">The database to be used from the Data Application Block of the Microsoft Enterprise Library.</param>
    /// <param name="mappingId">The mapping that defines the object persistance information.</param>
    /// <param name="objectId">The id of the object from the given mapping.</param>
    /// <param name="objectToRemove">The object to remove.</param>
    /// <returns>The number of rows affected by the transaction</returns>
    int RemoveObject(Database database, string mappingId, string objectId, object objectToRemove);
  }
}
